//
//  socket.c 
//  Socket SERVER SIDE
//
//  Created by Laurent Novac on 04.03.11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "socket.h"



/*------------------------------------------------------------
 
 We first need to create a socket to configure the connection
 then we have to do parameter it to communicate with the client
 then close the connection    
 
 ------------------------------------------------------------*/
/*------------------------------------------------------------
 This structure represents the paramater for connections (addressing context)
 
 struct sockaddr_in
 {
 short      sin_family;          // doc:http://www.gnu.org/software/libc/manual/html_node/Address-Formats.html#Address-Formats 
 unsigned short   sin_port;      //used port, must be returned by htons(unsigned short int port) which convert from host byte order to network byte
 //order (big endian)
 struct   in_addr   sin_addr;    //returned from htonl(unsigned integer hostlong) must be return IP address can be specified with inet_addr(char* IP)
 char   sin_zero[8];             //this is only an array of zero to complete the size of the structure, for cast in struct sockaddr, so we can use both
 //struct sockaddr is the same as sockaddr_in but less verbose struct sockaddr{u_short sa_family,char data[14]};
 //in fact sockaddr describes a network address and sockaddr_in a tcp/ip adress (IP and PORT)
 };
 ------------------------------------------------------------*/

void socket_server()
{
    int i;
#if defined (WIN32)
    WSADATA WSAData; //init routine for WSAStartup necessary for using socket on windows
    WSAStartup(MAKEWORD(2,2),&WSAData);
#endif
    SOCKET sock; 
    /*socket returns int
     INPUT: int: AF_INET for TCP_IP, AF_UNIX for local unix communication
     int: SOCK_STREAM for TCP, SOCK_DGRAM for UDP
     int: protocol, we don't need it, so we allways set to 0
     */
    /*declaration and initialisation of the adressing context of the server*/
    if ((sock=socket(AF_INET,SOCK_STREAM,0))>=0)
    {
        SOCKADDR_IN sin;
        sin.sin_family=AF_INET;
        sin.sin_port=htons(_PORT_);
        sin.sin_addr.s_addr=htonl(INADDR_ANY); //INADDR_ANY IP automatically given to server
        
        /*socket and adressing context of the client*/
        SOCKET clientSock;
        SOCKADDR_IN clientSin;
        socklen_t clientSinSize=sizeof(clientSinSize);
        for(i=0;i<8;i++){sin.sin_zero[i]=0;}
        
        if(!(bind(sock, (SOCKADDR*)&sin, sizeof(sin))))//binds the config to the adress context to the socket return SOCKET_ERROR if fail
        {
            if(!listen(sock,5))//the second arg is the backlog (maximum number of connexion that can be set to wait in the queue in general we put 5)
            {
                if((clientSock=accept(sock,(SOCKADDR*)&clientSin,&clientSinSize))>=0)//will block the process until a connection is made and the return is the socket on which we send to the client
                {
                    closesocket(sock);
                }
                
            }
        } 
    }
    else
    {
        printf("Erreur: %d",errno);
    }
    
#if defined (WIN32)
    WSACleanup();
#endif
}
void socket_client()
{
#if defined (WIN32)
    WSADATA WSAData; //init routine for WSAStartup necessary for using socket on windows
    WSAStartup(MAKEWORD(2,2),&WSAData);
#endif
    SOCKET sock;
    SOCKADDR_IN sinServer;
    sock=socket(AF_INET, SOCK_STREAM, 0);//socket creation
    sinServer.sin_family=AF_INET;//defining of the adressing context of the server
    sinServer.sin_port=htons(_PORT_);
    sinServer.sin_addr.s_addr=inet_addr("127.0.0.1");
    if(connect(sock,(SOCKADDR*)&sinServer,sizeof(sinServer))!=SOCKET_ERROR)//connection to the server
    {
        printf("\nConnection Established\n");
    }
    else
    {
        printf("Connection error %d",errno);
    }
    
    closesocket(sock);
    
#if defined (WIN32)
    WSACleanup();
#endif
    
}



